package servicios;

import java.net.URI;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;

import modelo.adaptadores.EntradaAdapter;
import modelo.datos.Entrada;
import modelo.datos.Persona;

import persistencia.BaseDatos;
import persistencia.BaseDatosImpl;

@Path("agenda")
public class AgendaREST {
	@Context
	private UriInfo uriInfo;

	public AgendaREST() {
		super();
	}

	// Caching con fechas
//	@GET
//	@Produces(MediaType.APPLICATION_XML)
//	public Response agenda(@Context Request request) {
//		Date ultimaModificacion = datos.getUltimaModificacion();
//		Response.ResponseBuilder responseBuilder = request.evaluatePreconditions(ultimaModificacion);
//		if(responseBuilder != null)
//			return responseBuilder.build();
//		return Response.ok(datos.getEntradas()).lastModified(ultimaModificacion).build();
//	}
	
	// Caching con Etags
	@GET
	@Produces(MediaType.APPLICATION_XML)
	public Response agenda(@Context Request request, @HeaderParam("Accept") String header) {
		System.out.println("Cabecera Accept:" + header);
		EntityTag tag = new EntityTag(BaseDatos.DATOS.hashCode()+"");
		ResponseBuilder responseBuilder = request.evaluatePreconditions(tag);
		if(responseBuilder != null)
			return responseBuilder.build();
		return Response.ok(BaseDatos.DATOS.getEntradas()).tag(tag).build();
	}


//	@GET
//	@Produces(MediaType.APPLICATION_XML)
//	public Response agenda(@Context Request request) {
//		return Response.ok(BaseDatos.DATOS.getEntradas()).build();
//	}
	
//	@GET
//	@Produces(MediaType.APPLICATION_XML)
//	@Path("{nif}")
//	public Response buscaEntradaPorNIF(@PathParam("nif") String nif) throws Exception {
//		Entrada entrada = BaseDatos.DATOS.buscaEntradaPorNIF(nif);
//		if (entrada == Persona.NULL)
//			return Response.status(Status.NOT_FOUND).build();
//		return Response.ok(entrada).build();
//	}
	
	@GET
	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
	@Path("{nif}")
	public Response buscaEntradaPorNif(@PathParam("nif") String nif, @Context Request request) {
		Entrada entrada = BaseDatos.DATOS.buscaEntradaPorNIF(nif);
		if (entrada == BaseDatos.ENTRADA_NULL)
			return Response.status(Status.NOT_FOUND).build();
		EntityTag etag = new EntityTag(entrada.hashCode() + "");
		ResponseBuilder responseBuilder = request.evaluatePreconditions(etag);
		if(responseBuilder != null)
			return responseBuilder.build();
		return Response.ok(entrada).tag(entrada.hashCode() + "").build();
	}

	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response nuevaEntradaDesdeFormulario(
			@FormParam("nombre") String nombre,
			@FormParam("apellidos") @DefaultValue("") String apellidos,
			@FormParam("nif") String nif) {
		if (BaseDatos.DATOS.buscaEntradaPorNIF(nif) == BaseDatos.ENTRADA_NULL) {
			if ("".equals(apellidos)) // Si el parámetro no existe, llega un
										// null.
				BaseDatos.DATOS.nuevaEmpresa(nombre, nif);
			else
				BaseDatos.DATOS.nuevaPersona(nombre, apellidos, nif);
			UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
			URI uri = uriBuilder.path(nif).build();
			// System.out.println(uri.toString());
			return Response.created(uri).build();
		} else
			return Response.status(Status.CONFLICT).build();
	}

	@PUT
	@Path("/{nif}")
	@Consumes(MediaType.APPLICATION_XML)
	public Response actualizaEntrada(@PathParam("nif") String nif, EntradaAdapter.AdaptedEntrada entrada) throws Exception{
		if (nif.equals(entrada.nif) == false)
			return Response.status(Status.BAD_REQUEST).build();
		else {
			EntradaAdapter adaptador = new EntradaAdapter();
			Entrada laEntrada = adaptador.unmarshal(entrada);
			if (BaseDatos.DATOS.actualizaEntrada(laEntrada) == false)
			return Response.status(Status.NOT_FOUND).build();
		}
		return Response.status(Status.NO_CONTENT).build();
	}
	
	@DELETE
	@Path("/{nif}")
	public Response borraEntrada(@PathParam("nif") String nif) {
		if (nif != null) {
			if (BaseDatos.DATOS.borraEntrada(nif) == true)
				return Response.status(Status.ACCEPTED).build();
			else
				return Response.status(Status.NOT_FOUND).build();

		} else
			return Response.status(Status.BAD_REQUEST).build();
	}

	// No hace falta, Jersey los genera automaticamente
	//	@HEAD
	// @OPTIONS
}